package com.common.www.utils;

import com.luciad.imageio.webp.WebPReadParam;

import org.apache.commons.lang3.StringUtils;

import java.awt.Color;
import java.awt.Graphics;
import java.awt.Graphics2D;
import java.awt.image.BufferedImage;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;

import javax.imageio.ImageIO;
import javax.imageio.ImageReader;
import javax.imageio.stream.FileImageInputStream;

import sun.misc.BASE64Decoder;
import sun.misc.BASE64Encoder;

public class ImageUtils {
    /**
     * @param path 图片路径
     * @return
     * @Descriptionmap 将图片文件转化为字节数组字符串，并对其进行Base64编码处理
     * @author temdy
     * @Date 2015-01-26
     */
    public static String imageToBase64(String path) {// 将图片文件转化为字节数组字符串，并对其进行Base64编码处理
        byte[] data = null;
        // 读取图片字节数组
        try {
            InputStream in = new FileInputStream(path);
            data = new byte[in.available()];
            in.read(data);
            in.close();
        } catch (IOException e) {
            e.printStackTrace();
        }
        // 对字节数组Base64编码
        BASE64Encoder encoder = new BASE64Encoder();
        return encoder.encode(data);// 返回Base64编码过的字节数组字符串
    }

    /**
     * data:image/jpeg;base64,
     *
     * @param base64 图片Base64数据  需要去掉前缀例如data:image/jpeg;base64,
     * @param path   图片路径
     * @return
     * @Descriptionmap 对字节数组字符串进行Base64解码并生成图片
     * @author temdy
     * @Date 2015-01-26
     */
    public static boolean base64ToImage(String base64, String path) {// 对字节数组字符串进行Base64解码并生成图片
        if (base64 == null) { // 图像数据为空
            return false;
        }
        BASE64Decoder decoder = new BASE64Decoder();
        try {
            // Base64解码
            byte[] bytes = decoder.decodeBuffer(base64);
            for (int i = 0; i < bytes.length; ++i) {
                if (bytes[i] < 0) {// 调整异常数据
                    bytes[i] += 256;
                }
            }
            // 生成jpeg图片
            OutputStream out = new FileOutputStream(path);
            out.write(bytes);
            out.flush();
            out.close();
            return true;
        } catch (Exception e) {
            return false;
        }
    }

    /**
     * 吧图片中白色部分替换为透明
     */
    public static BufferedImage deleteImageWhite(BufferedImage image) {
        // 遍历图片的每个像素
        for (int x = 0; x < image.getWidth(); x++) {
            for (int y = 0; y < image.getHeight(); y++) {
                // 获取像素的颜色
                Color color = new Color(image.getRGB(x, y));

                // 检查颜色是否为白色
                if (color.equals(Color.WHITE)) {
                    // 将像素设置为透明
                    image.setRGB(x, y, new Color(0, 0, 0, 0).getRGB());
                }
            }
        }

//        // 将处理后的图片保存到文件
//        File output = new File("output.png");
//        ImageIO.write(image, "png", output);

        return image;
    }

    /**
     * 二值化图片
     *
     * @param threshold 二值化阈值根据这个值来进行分割推荐128
     */
    public static void binaryzationImage(String filePath, int threshold) throws IOException {
        // 读取原始图像
        BufferedImage image = ImageIO.read(new File(filePath));

        // 创建二值化图像
        BufferedImage binarizedImage = new BufferedImage(image.getWidth(), image.getHeight(), BufferedImage.TYPE_BYTE_BINARY);

        for (int y = 0; y < image.getHeight(); y++) {
            for (int x = 0; x < image.getWidth(); x++) {
                int rgb = image.getRGB(x, y);
                Color color = new Color(rgb);
                int gray = (color.getRed() + color.getGreen() + color.getBlue()) / 3;
                if (gray >= threshold) {
                    binarizedImage.setRGB(x, y, Color.WHITE.getRGB());
                } else {
                    binarizedImage.setRGB(x, y, Color.BLACK.getRGB());
                }
            }
        }

        // 保存二值化图像
//        ImageIO.write(binarizedImage, "jpg", new File("output.jpg"));
        ImageIO.write(binarizedImage, FileUtils.getSuffix(filePath), new File(filePath));
    }

    /**
     * 反色
     */
    public static void antiColor(String filePath, String outputFilePath) throws IOException {
        BufferedImage img = ImageIO.read(new File(filePath));
        int width = img.getWidth();
        int height = img.getHeight();

        for (int x = 0; x < width; x++) {
            for (int y = 0; y < height; y++) {
                int r = img.getRGB(x, y);

                int red = (r >> 16) & 0x0ff;
                int green = (r >> 8) & 0x0ff;
                int blue = r & 0x0ff;

                red = 255 - red;
                green = 255 - green;
                blue = 255 - blue;

                r = (red << 16) | (green << 8) | blue;
                img.setRGB(x, y, r);
            }
        }
        ImageIO.write(img, FileUtils.getSuffix(filePath), new File(outputFilePath));
    }

    /**
     * 是否是webp图片
     */
    public static boolean isWebp(String nameOrPath) {
        String suffix = FileUtils.getSuffix(nameOrPath);
        if (StringUtils.equals(suffix, "webp") || StringUtils.equals(suffix, "WEBP")) {
            return true;
        }
        return false;
    }


    /**
     * 图片webp文件转png文件
     *
     * @param webpFile   源webp文件
     * @param outputFile 转换后文件,支持jpg和png
     * @return
     * @throws IOException
     */
    public static File webpToImg(File webpFile, File outputFile) throws IOException {
        // Obtain a WebP ImageReader instance
        ImageReader reader = ImageIO.getImageReadersByMIMEType("image/webp").next();

        // Configure decoding parameters
        WebPReadParam readParam = new WebPReadParam();
        readParam.setBypassFiltering(true);

        // Configure the input on the ImageReader
        reader.setInput(new FileImageInputStream(webpFile));

        // Decode the image
        BufferedImage image = reader.read(0, readParam);

        //the `png` can use `jpg`
        String suffix = FileUtils.getSuffix(outputFile.getAbsolutePath());
        ImageIO.write(image, suffix, outputFile);
        return outputFile;
    }

    /**
     * 创建纯色图
     */
    public static BufferedImage createPureImage(int width, int height, Color c) {
        // 创建一个 BufferedImage 对象
        BufferedImage image = new BufferedImage(width, height, BufferedImage.TYPE_INT_ARGB);

        // 获取图像的绘制上下文对象
        Graphics g = image.getGraphics();

        // 设置绘制颜色为黑色
        g.setColor(c);

        // 填充整个图像区域
        g.fillRect(0, 0, width, height);

        // 释放绘制上下文资源
        g.dispose();

        return image;
    }

    /**
     * 合并两张图
     */
    public static BufferedImage mergeImages(BufferedImage background, Integer x, Integer y, Integer width, Integer height, BufferedImage overlay) {
        Graphics g = background.getGraphics();
        g.drawImage(overlay, x, y, width, height, null);
        g.dispose();
        return background;
    }

    /**
     * 保存到本地
     */
    public static void saveImage(BufferedImage image, String fileName) {
        try {
            // 保存图像到文件
            ImageIO.write(image, "png", new File(fileName));
            System.out.println("图像保存成功！");
        } catch (IOException e) {
            System.out.println("图像保存失败：" + e.getMessage());
        }
    }

    /**
     * 缩放图片
     */
    public static BufferedImage scaleImage(BufferedImage inputImage, int scaledWidth, int scaledHeight) {
        BufferedImage outputImage = new BufferedImage(scaledWidth, scaledHeight, inputImage.getType());
        Graphics2D g2d = outputImage.createGraphics();
        g2d.drawImage(inputImage, 0, 0, scaledWidth, scaledHeight, null);
        g2d.dispose();
        return outputImage;
    }

    /**
     * 绘制矩形
     */
    public static void drawRectangle(BufferedImage bufferedImage, int x, int y, int width, int height, Color color) {
        Graphics2D g2d = bufferedImage.createGraphics();
        g2d.setColor(color);
        g2d.fillRect(x, y, width, height);
    }

}
